package demo.practice.competition;

public class P1861 {

    /**
     * 给你一个m x n的字符矩阵box，它表示一个箱子的侧视图。箱子的每一个格子可能为：
     * <p>
     * '#'表示石头
     * '*'表示固定的障碍物
     * '.'表示空位置
     * 这个箱子被 顺时针旋转 90 度，由于重力原因，部分石头的位置会发生改变。每个石头会垂直掉落，直到它遇到障碍物，另一个石头或者箱子的底部。重力 不会影响障碍物的位置，同时箱子旋转不会产生惯性，也就是说石头的水平位置不会发生改变。
     * <p>
     * 题目保证初始时box中的石头要么在一个障碍物上，要么在另一个石头上，要么在箱子的底部。
     * <p>
     * 请你返回一个n x m的矩阵，表示按照上述旋转后，箱子内的结果。
     * <p>
     * 来源：力扣（LeetCode）
     * 链接：https://leetcode-cn.com/problems/rotating-the-box
     * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
     * <p>
     * 输入：box = [["#",".","*","."],
     *             ["#","#","*","."]]
     * 输出：[["#","."],
     *       ["#","#"],
     *       ["*","*"],
     *       [".","."]]
     * <p>
     * 来源：力扣（LeetCode）
     * 链接：https://leetcode-cn.com/problems/rotating-the-box
     * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
     */

    public static void main(String[] args) {
        P1861 p1861 = new P1861();
        p1861.rotateTheBox(new char[][]{{'#', '.', '#'}});
    }

    public char[][] rotateTheBox(char[][] box) {
        //先不考虑重力的情况，推导一下转换关系.  设返回的结果数组为B,原转换的数组为 A
        // A[[1,2,3],
        //   [4,5,6]]


        //B[[4,1],          Ay=Bx
        //  [5,2],          Ax=len-1-By
        //  [6,3]
        // ]


        // B[x][y]= A[len-1-y][x]  其中len为A的行数即 box.length
        //举例说明   B[0,0]= 4 = A[2-1-0][0]= A[1][0]
        //          B[1,1]= 2=  A[2-1-1][1]= A[0][1]


        //  A[[1,2,3]]

        //B[[1],
        //  [2],
        //  [3]]        B[0][0]=A[0][0]  B[0][0]

        //因为有重力作用，所以我们可以从 B的 最后一行，往上来填值，
        //这样只要当前值的  垂直方向有  塌陷，就下坠（注意这里要用while，因为有可能 会 一直 坠落到底部）
        if (box == null || box.length == 0)
            return box;

        int len = box.length;
        //int m= len;
        int n = box[0].length;

        char[][] target = new char[n][len];
        for (int x = target.length - 1; x >= 0; x--) {
            //char[] level= target[x];
            for (int y = 0; y < target[x].length; y++) {

                //要填充的值如果为'.'（空位置） 或者 *（障碍物） 直接填充就可以了
                if (box[len - 1 - y][x] == '.' || box[len - 1 - y][x] == '*') {
                    target[x][y] = box[len - 1 - y][x];
                    continue;
                }
                int xcol = x;  //xcol代表 target垂直方向 此时的x
                while (xcol < target.length - 1 && target[xcol + 1][y] == '.') {//代表可以下坠
                    xcol++;
                }
                target[xcol][y] = box[len - 1 - y][x];
                if(xcol>x)
                    target[x][y]='.';//把当前的空填上
            }
        }
        return target;
    }

}
